package cn.tedu.ivos.audit.service.impl;

import cn.tedu.ivos.application.mapper.ApplicationMapper;
import cn.tedu.ivos.application.pojo.entity.Application;
import cn.tedu.ivos.audit.mapper.AuditMapper;
import cn.tedu.ivos.audit.pojo.dto.AuditQuery;
import cn.tedu.ivos.audit.pojo.dto.AuditSaveParam;
import cn.tedu.ivos.audit.pojo.entity.Audit;
import cn.tedu.ivos.audit.pojo.vo.AuditVO;
import cn.tedu.ivos.audit.service.AuditService;
import cn.tedu.ivos.base.enums.ApplicationStatusEnum;
import cn.tedu.ivos.base.enums.AuditStatusEnum;
import cn.tedu.ivos.user.mapper.UserMapper;
import cn.tedu.ivos.user.pojo.vo.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringJoiner;

/**
 * 审核业务实现类
 * 提供审核相关的增删改查、状态更新等操作
 */
@Transactional // Spring 的事务管理注解，确保所有数据库操作在同一个事务中执行
@Slf4j // Lombok 注解，用于生成日志记录器
@Service // 标记为 Spring 服务组件
public class AuditServiceImpl implements AuditService {

    @Autowired
    private AuditMapper auditMapper; // 审核数据访问层

    @Autowired
    private ApplicationMapper applicationMapper; // 申请单数据访问层

    @Autowired
    private UserMapper userMapper; // 用户数据访问层

    /**
     * 添加审核信息
     *
     * @param application 申请单对象，包含审核人列表
     */
    @Override
    public void insertAudit(Application application) {
        log.debug("开始处理【添加审核】的业务，参数：{}", application);
        List<Long> auditUserIdList = application.getAuditUserIdList(); // 获取审批人ID集合
        for (int i = 0; i < auditUserIdList.size(); i++) {
            Audit audit = new Audit();
            audit.setApplicationId(application.getId());
            audit.setAuditUserId(auditUserIdList.get(i));
            audit.setAuditSort(i);
            if (i == 0) {
                // 第一条审批数据，对应直属领导，状态为“待我审核”
                audit.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode());
            } else {
                // 非第一条，对应其他人，状态为“待他人审核”
                audit.setAuditStatus(AuditStatusEnum.PENDING.getCode());
            }
            audit.setCreateTime(new Date()); // 设置创建时间
            auditMapper.insertAudit(audit); // 插入审核记录
        }
    }

    /**
     * 根据申请单 ID 查询审核信息
     *
     * @param applicaitionId 申请单 ID
     * @return 审核信息列表
     */
    @Override
    public List<AuditVO> selectAuditByApplicationId(Long applicaitionId) {
        log.debug("开始处理【查询审核】的业务，参数：{}", applicaitionId);
        List<AuditVO> list = auditMapper.selectAuditByApplicationId(applicaitionId);
        return list;
    }

    /**
     * 根据用户名查询审核信息
     *
     * @param auditQuery 查询条件
     * @return 审核信息列表
     */
    @Override
    public List<AuditVO> selectAuditByUsername(AuditQuery auditQuery) {
        log.debug("开始处理【查询审批单】的业务，参数：{}", auditQuery);
        List<AuditVO> list = auditMapper.selectAudit(auditQuery);
        for (int i = 0; i < list.size(); i++) {
            AuditVO auditVO = list.get(i);
            assignAuditUserList(auditVO); // 分配审核人名称
        }
        return list;
    }

    /**
     * 更新审核信息
     *
     * @param auditSaveParam 审核保存参数
     */
    @Override
    public void updateAudit(AuditSaveParam auditSaveParam) {
        // 记录方法调用开始，方便调试查看传入参数
        log.debug("开始处理【更新审批单】的业务，参数：{}", auditSaveParam);

        // 创建 Application 对象，并设置申请单 ID，用于后续更新状态
        Application application = new Application();
        application.setId(auditSaveParam.getApplicationId());

        // 创建 Audit 对象，并将传入的参数拷贝到该对象中
        Audit audit = new Audit();
        BeanUtils.copyProperties(auditSaveParam,audit); // 属性拷贝，避免手动 set
        audit.setUpdateTime(new Date()); // 设置审核记录的更新时间
        auditMapper.updateAudit(audit); // 调用 Mapper 更新数据库中的审核记录

        log.debug(audit.toString());
        // 判断当前审核状态是否为“已审核通过”
        if (audit.getAuditStatus().equals(AuditStatusEnum.AUDITED.getCode())) {
            // 构建查询条件，用于查找剩余待审核的审批人
            AuditQuery auditQuery = new AuditQuery();
            auditQuery.setApplicationId(audit.getApplicationId()); // 设置申请单 ID 查询条件

            // 查询还有多少个待审核的审批人
            Integer count = auditMapper.selectRestAuditCount(auditQuery);

            // 如果还有未审核的审批人
            if (count > 0) {
                // 设置查询下一个审批人的排序编号（当前审批人 +1）
                auditQuery.setAuditSort(audit.getAuditSort() + 1);
                log.debug("查询下一个待审核的审批人信息，参数：{}", auditQuery);
                // 查询下一位需要审核的审批人信息
                List<AuditVO> auditUserList = auditMapper.selectAudit(auditQuery);

                // 如果存在下一位审批人
                if (!auditUserList.isEmpty()) {
                    // 获取第一个待审核审批人信息
                    AuditVO auditVO = auditUserList.get(0);

                    // 创建新的 Audit 对象并设置其状态为“待我审核”
                    Audit audit2 = new Audit();
                    audit2.setId(auditVO.getId());
                    audit2.setAuditStatus(AuditStatusEnum.MY_PENDING.getCode()); // 设置为待我审核
                    audit2.setUpdateTime(new Date()); // 设置更新时间

                    // 更新数据库中该审批人的状态
                    auditMapper.updateAudit(audit2);
                }

                // 设置申请单状态为“审核中”
                application.setStatus(ApplicationStatusEnum.AUDIT.getCode());
                applicationMapper.updateApplication(application); // 更新申请单状态
            } else {
                // 如果没有剩余待审核人，表示整个流程已完成

                // 设置申请单状态为“已审核”
                application.setStatus(ApplicationStatusEnum.AUDITED.getCode());
                applicationMapper.updateApplication(application); // 更新申请单状态
            }
        } else {
            //更新申请单状态为“驳回”
            application.setStatus(ApplicationStatusEnum.REJECT.getCode());
            application.setRejectReason(auditSaveParam.getRejectReason());
            applicationMapper.updateApplication(application);
            if (audit.getAuditSort()==0){
                //更新审核状态为“驳回”
                audit.setUpdateTime(new Date());
                audit.setAuditStatus(AuditStatusEnum.REJECT.getCode());
                audit.setUpdateTime(new Date());
                auditMapper.updateAudit(audit);
                //删除其他审批单
                AuditQuery auditQuery = new AuditQuery();
                auditQuery.setApplicationId(audit.getApplicationId());
                Integer count = auditMapper.selectRestAuditCount(auditQuery);
                Long applicationId =audit.getApplicationId(); // 设置申请单 ID 查询条件
                Integer auditSort = audit.getAuditSort();
                for (int i = 0; i < count; i++) {
                    auditSort = auditSort + 1;
                    auditMapper.deleteAuditByApplicationIdAndSort(applicationId, auditSort);
                }
            }else {
                //更新审核状态为“驳回”
                audit.setUpdateTime(new Date());
                audit.setAuditStatus(AuditStatusEnum.REJECT.getCode());
                audit.setUpdateTime(new Date());
                auditMapper.updateAudit(audit);
            }
        }
    }


    /**
     * 给每个审核 VO 赋值审核人名称和 ID 列表
     *
     * @param auditVO 审核 VO 对象
     */
    private void assignAuditUserList(AuditVO auditVO) {
        List<Long> auditUserIdList = new ArrayList<>();
        List<String> auditUsernameList = new ArrayList<>();

        List<AuditVO> auditUserList = auditMapper.selectAuditByApplicationId(auditVO.getApplicationId());
        for (int i = 0; i < auditUserList.size(); i++) {
            Long id = auditUserList.get(i).getAuditUserId();
            auditUserIdList.add(id);
            UserVO userVO = userMapper.selectById(id);
            auditUsernameList.add(userVO.getUsername());
        }

        StringJoiner auditUsernameListStringJoiner = new StringJoiner(",");
        for (String auditUsername : auditUsernameList) {
            auditUsernameListStringJoiner.add(auditUsername);
        }

        auditVO.setAuditUsernameList(auditUsernameListStringJoiner.toString());
        auditVO.setAuditUserIdList(auditUserIdList);
    }
}
